Copyright: ®1993-1995 SoftDesign


Help Contents
Contents

Welcome

The RIP Family

Introducing RipTABS

Registration & Licensing

Feedback & Support

New In This Version

Installation & Packing List

Overview

Interface Primer - Folder Tab Dialogs

What RipTABS Does For You

Function Groups

Things To Know & Remember

Font Notes

Bitmap Notes

Troubleshooting

Implementation

Requirements

About The Sample Source Code

Building Your Dialogs (Resource Editor)

Adding The Support Code

Final Touch-Ups

Reference

RipTABRegister

RipTABUnregister

CTabDialog::CTabDialog

CTabDialog::DisableTab

CTabDialog::EnableTab

CTabDialog::GetTabText

CTabDialog::InitData

CTabDialog::IsTabEnabled

CTabDialog::NextTab

CTabDialog::PrevTab

CTabDialog::OKToSwitch

CTabDialog::OnCancel

CTabDialog::OnDestroy

CTabDialog::OnInitDialog

CTabDialog::OnLButtonDown

CTabDialog::OnOK

CTabDialog::OnPaint

CTabDialog::SetActiveTab

CTabDialog::SetTabText

CTabDialog::SwitchToNotification

CTabDialog::SwitchFromNotification


The RIP Family

RipTABS is a library derived from code originally written for a number of other applications that sport the RIP title from SoftDesign.  Take a moment to read about them.

The RIP family of applications / utilities is a collection of shareware programs written for Windows and Windows NT.  Each is designed to fulfill a purpose in an elegant, easy-to-use fashion.

All RIP applications have a registration fee which you are expected to pay if you continue to use them.  The amounts asked for are reasonable and I ask that you think twice about continuing to use something you haven't paid for.  None of the RIP applications have disabled functions, or annoying "Register Me" reminders-- so I leave it up to you.

RipBAR - The Application ToolBar For Windows & Windows NT

RipBAR is an application toolbar that you may set up with applications and documents of your choice.  Configuration options for each item include the ability to set up startup directory, and command line parameters.  Additionally, files may be dropped onto the application icons sitting on the bar-- causing the application to launch and open that file automatically.

The Windows 3.1 version displays the time, memory information, and the remaining resources available to the system.  The Resource Tracker (Windows 3.1 only) is included to allow you to monitor an application's use of memory and resources.

The Windows NT version displays the time, along with available physical and paged RAM.  It also includes the Performance Tool -- displaying summary information about CPU performance.

In addition, RipBAR supports attaching sound to certain types of events, HotKey activation, program groups, a Post-It style Notes feature and much more.

Was recently written up in Windows Magazine & PC Week Magazine.

RipSPACE - The Disk Space Reporting Tool For Windows & Windows NT

RipSPACE is an application written for Windows & Windows NT that analyzes a drive and the space that each sub directory on it, consumes.  In other words, you'll now be able to find out how much space your Windows installation is taking up, or how much drive space you'll gain if you delete the WordPounder word processor you installed but never use.

RipSPACE also allows you to define file types that are to be included in a file report.  You can then tell how much total space is being taken up by certain file types-- i.e. Bitmaps, Dynamic Link Libraries and executable files.

Jonathan Carroll


Introducing RipTABS

(See the end of this section for important information regarding this unregistered version)

RipTABS is a C++ library designed for applications that use Microsoft Foundation Class Library support.  It provides developers with an easy-to-use path to the dialog folder tab interface that is becoming popular in a number of new Windows applications including Word 6 and Excel 5 from Microsoft.  For more information on what tab dialogs look like and why they are important, see Interface Primer - Folder Tab Dialogs.

The RipTABS library is provided for both Windows 3.1 (Windows For Workgroups 3.1, 3.11) and Windows NT.  These are available as separate downloads from CompuServe.  (Both appear in the MSLANG forum libraries.)

Specifically, RipTABS provides you with an MFC-based CDialog class called CTabDialog from which you can derive dialog classes anywhere where you derive from CModalDialog or CDialog.

RipTABS is particularly easy to implement because it shouldn't be necessary to change much of your existing code to make use of the folder tab interface-- in other words, much of the new functionality you'll get will be for free!

Please read carefully through all of the topics in this help file as there are a number of issues concerning memory management and the like that you should be aware of.  Resisting the temptation to save a few minutes by not reading through the documentation now, will save you hours of trouble later.

Using the Unregistered Version

If you have not registered RipTABS, then it is presumed that you are evaluating this library-- you're expected to pay the registration fee if you actually use it in your programs.

The unregistered version will always place the library  title and a copyright notice in the title of any RipTABS dialog.  You should not attempt to modify the dialog box caption text through a call to SetWindowText or some other call because the library code checks the title from time to time, and if it finds the text has been modified, the dialog box will stop painting (updating) itself.  The dialog will also stop working properly if you set the dialog style such that there is no title bar.

Note too that the demo version of the library is a large memory model version and it must be linked with a program built in debug mode in Visual C++.

Other than the pre-set dialog box caption text, this library is fully functional with respect to the registered / release version.


Registration & Licensing

Registration
RipTABS is available free from various on-line service including CompuServe.  What you get, is an evaluation copy of the library, documentation, and some sample source code.  You should have enough to determine whether you like the RipTABS implementation of tab dialogs and whether it is suitable for your purposes.

You should know that the unregistered version will always place the library  title and a copyright notice in the title of any RipTABS dialog.  You should not attempt to modify the dialog box caption text through a call to SetWindowText or some other call because the library code checks the title from time to time, and if it finds the text has been modified, the dialog box will stop painting (updating) itself.  The dialog will also stop working properly if you set the dialog style such that there is no title bar.

Should you want to continue using it, there is a $60 registration fee.  For this fee, you'll have access to support (via electronic mail) for the library, notification of new releases.  Printed documentation is also available for a nominal charge.  Of course, you'll also get a release version of the library that doesn't set the caption text of dialogs with RipTABS copyright information and versions for memory models other than the Large Memory Model.

The $60 will get you one complete version of the compiled library-- either for Windows or Windows NT.  If you purchase both libraries at once, the package price is $100.

Source code is available for $150 and you can request compiled builds of the library for no additional charge.  In addition to allowing you to customize the code for your own use (to make tabs on MFC CFormViews etc.), the source code option allows you to incorporate RipTABS into MFC applications built with the DLL version of the MFC library-- something the compiled library alone doesn't support.

You may register each of these RipTABS options via CompuServe by typing GO SWREG at any CompuServe prompt.  Once there, do a search with the keyword RIPTABS.

License
When you purchase a RipTABS library, you may use it to build applications and you can distribute and/or sell your applications that include RipTABS dialogs without any additional royalties.

However, you may not redistribute the library itself-- nor may you include the RipTABS library in any other library that you build for the purpose of delivering some kind of "enhancements" tool to third parties.  In other words, RipTABS may only be included in an application (whether that inclusion be in the form of an executable file or dynamic link library.)

You must purchase one copy of RipTABS for every developer who will be using the library.


Feedback & Support

Feedback
This is the sixth release of the RipTABS dialog library.

Should you find a problem with the library, or have any suggestions for improvement (with either the library or this documentation) please do not hesitate to contact me at one of the addresses listed below.

Support
Support for RipTABS (i.e. implementation, design etc.) is provided to those who have registered RipTABS.  You can contact me at one of the addresses listed below.

Reaching Me

CompuServe (preferred method)

Support Forum: Section 20 (SoftDesign) of the WINAPE forum.
Email: 74777,2357

Internet
74777.2357@compuserve.com

Conventional Mail
Jonathan Carroll
28 Parkland
Pointe Claire, Quebec
Canada, H9R 2E8


New In This Version

New In Version 4.0

New In Version 3.0a

New In Version 2.1

New In Version 2.0


New In Version 4.0

This is Version 4.0 of RipTABS.

The following is new or improved in the latest release:

•	RipTABS now supports vertical tabs in dialogs

•	RipTABS now provides support for specifying the color of the active and non-active tabs.

•	RipTABS now provides support for disabling and enabling tabs

•	RipTABS now provides support for setting and retrieving the text in individual tabs on the fly.

•	You may now choose the font that will be used to draw all controls in a dialog.

•	RipTABS can now build the all three customizable fonts for you-- just pass the RipTABS-define STDFont for the font parameters and RipTABS will choose appropriate fonts for each.

•	RipTABS now provides complete and proper support for MFC DDX routines.

•	This release of RipTABS provides proper support for key accelerators.  In other words, you may define controls on different tab pages with the same accelerator and RipTABS will handle the conflict by disabling the accelerators on those controls that aren't currently visible to the user.

•	Previously, RipTABS had problems displaying editable combo boxes on the main dialog form-- this problem has been resolved in this release.

•	Previously, if a user pressed the ESC key while a tab title had keyboard focus, the dialog wouldn't close.  This is fixed.

•	RipTABS now makes use of the MFC OnDestroy message to perform some extra cleanup-- if you are currently overriding this member, be sure to call the base class function (in CTabDialog) too.


New In Version 3.0a

•	You may now include bitmaps in addition to text in dialog tabs.

•	Tabs may now be configured to appear with either rounded or square corners.

•	You may now select the font that gets displayed in the tabs.  This means that RipTABS can now display the active tab in a bolded font.

•	A new RipTABS callback message has been implemented : OKToSwitch.  This allows you to decide that access to a particular tab is off limits for a particular reason.

•	You may now tell RipBAR to limit the number of tabs per page (or per line) to a limit that you specify.

•	The tab with focus is highlighted with the standard focus rectangle (was previously a solid grey line.).

•	Minor drawing enhancements have been made.


New In Version 2.1

•	The are two functions which previously existed but are now documented for use -- PrevTab, and NextTab.  See CTabDialog::PrevTab and CTabDialog::NextTab.

•	RipTABS contains a new function - SetTab() which allows you to activate a particular tab group in an active dialog.  See CTabDialog::SetActiveTab.

•	The CTabDialog constructor (for both Modal and Modeless dialogs) contains new parameters for setting an active tab group on dialog startup, and for building completely dynamic dialogs whose contents are only determined at runtime-- see CTabDialog::CTabDialog.

•	The InitData function provides for additional parameters -- see CTabDialog::InitData.

•	Pressing the cursor-up or cursor-left key while a tab has focus, causes the dialog to switch to the previous tab group.

•	Pressing the cursor-down or cursor-right key while a tab has focus, causes the dialog to switch to the next tab group.


New In Version 2.0

•	RipTABS contains two new functions -- RipTABSRegister() and RipTABSUnregister().  See the tutorial and Reference sections for more information-- including RipTABRegister and RipTABUnregister.

•	RipTABS now supports the use of hotkeys to switch between tabs.  For more information on how this works, see Interface Primer - Folder Tab Dialogs.

•	Full support is provided for modeless dialogs-- a number of omissions in the last release made modeless dialogs a problem.  A new constructor for the CTabDialog class is provided for this purpose.

•	Tab names are now controls that can receive focus-- this focus is displayed visually by a bounding rectangle.

•	When switching tabs, focus is now initially set to the active tab-- emulating the behavior in products like Microsoft Word and Excel.

•	Things To Know & Remember is a new section added to this guide.  It contains a number of caveats about using RipTABS, a few troubleshooting tips and highlights of important things to remember.

•	Problems that sometimes occurred when more than one control in the dialog had the same accelerator key, are now fixed.

•	Some people reported that during the link process, Visual C++ reported that some symbols (MFC ones) were defined twice-- this problem has been fixed.


Installation & Packing List

RipTABS is available in versions for both Windows and Windows NT.  The header file is common between the two versions-- just the library file is different.  The demo Windows NT lib file is RIPTAB32.LIB and the Windows one is RIPTAB16.LIB.  For descriptions of other libraries included with the registered version of RipTABS, see below.

The ZIP file you got, should contain two files-- the release notes in Windows Write format, and RIPT_LIB.ZIP.

To finish installing RipTABS, simply create a new directory anywhere on your system and extract all the files from RIPT_LIB.ZIP into it-- use the -d option (or whatever option your UnZip utility supports) to extract the files in the proper directory structures-- Building the sample application depends on the directory structure that has been set up for you in the ZIP file.

After extracting the files, there should be the RipTABS Windows Help file in a directory called HELP, the RipTABS include file in a directory called INCLUDE, and the sample code (including the executable file) in a directory called SAMPLE.

There will also be a CTL3D DLL in a directory called SYSTEM.  If you don't already have the same file in your Windows SYSTEM directory or if the one you have is older than the one supplied here with RipTABS, move it to your SYSTEM (or SYSTEM32 in NT) directory.

In the LIB directory, the files you have will depend on the version of RipTABS you have.

For Windows 16 bit:

•	RIPTAB16.LIB (demo version) Large Memory Model - Debug Build

•	RIPT_MCD.LIB (registered version) Medium Memory Model - Debug Build

•	RIPT_MCR.LIB (registered version) Medium Memory Model - Release Build

•	RIPT_LCD.LIB (registered version) Large Memory Model - Debug Build

•	RIPT_LCR.LIB (registered version) Large Memory Model - Release Build

For Windows NT:

•	RIPTAB32.LIB (demo version)

•	RIPT_NCR.LIB (registered version)  - Release Build

•	RIPT_NCD.LIB (registered version)  - Debug Build

Be sure to include the .LIB file for linking in any project you're going to use the RipTABS library with.


Interface Primer - Folder Tab Dialogs

Quick Introduction To Tabs
It's no secret -- the widespread acceptance of Windows and other graphically-oriented operating environments  has allowed applications to enable the user to do far more things in a wider variety of fashions that text-based systems could ever hope to offer.

One dilemma for those who write software is trying to present information and options to the user without becoming overwhelming.

In the next while, you'll notice the "Folder Tab" interface becoming increasingly popular.  Folder Tabs allow for the logical grouping of options and settings within one dialog-- doing away with millions of nested dialogs or menu items.  It also takes closer to the "desktop" metaphor.

The Folder Tab implementation in RipBAR is designed to closely resemble (both visually and in terms of behavior) those of Microsoft.  (Take a look at Word V6 or Excel V5)

Tab Interface Behavior
The Folder Tab dialog presents groups of options in pages.  Each page has a number of tabs.  For those with a mouse or similar input device, navigating the dialog is easy-- just click on a tab to bring that folder to the front.

Keyboard navigation is possible.  Pressing CTRL+TAB will cycle forward through the tabs and pressing CTRL+SHIFT+TAB will cycle backwards through the tabs.  In addition, when the tab title has input focus (the tab will be highlighted by a bounding rectangle), typing the first letter of another tab will cause that tab group to become active.

Each time a new tab group is activated, the tab for that group gains focus.  Pressing the TAB key will begin the navigation through the rest of the dialog's controls.


What RipTABS Does For You

In this section, we'll discuss the functionality that RipTABS provides to your applications and cover in a general sense what RipTABS is doing "behind the scenes".  If you haven't already read the material and looked at the figure in Interface Primer - Folder Tab Dialogs, it would be helpful to do that now before proceeding any further here.

Now that you know what tab dialogs look like, we'll discuss a little bit about how they behave (in case you haven't used an application that makes use of them).

Tab dialogs are actually made up of several dialogs.  First, you have what we are going to call a Master Dialog-- this is the dialog that frames all of the tab pages and usually contains a number of controls that are common to all tab pages-- i.e. OK, Cancel and possible Help.  (Note, this is a deviation form the Microsoft style dialogs, as the Master dialog normally contains no controls.)  Next you have what we'll call the Child Dialog-- there is one Child Dialog for each tab page in the Master Dialog.

You might for instance, have one Master dialog and five Child dialogs-- which means you'll have a tab dialog with five tab pages.

RipTABS does a number of jobs for you-- making the implementation of tab dialogs much easier than having to write the code from scratch.  (There's almost 5000 lines of code that has already been implemented for you in the library.)  Here's what RipTABS does :

•	Allows you to develop tabbed dialogs with tabs arranged either horizontally or vertically.

•	Scans the tab titles you pass it, and decides how big each tab needs to be.

•	Counts the tabs and re-sizes your dialog dynamically to make room for the tabs.  Tabs are arranged in multiple rows (stacked and offset) if necessary.

•	Draws bitmaps of your choosing for individual tabs.

•	Can automatically generate fonts for your dialog so that your dialogs take on a modern Windows look.

•	Handles user interface responsibilities such as responding to left-button mouse clicks, and hotkey and CTRL-TAB key presses to switch between dialog pages.

•	Dynamically manages memory to accommodate the Master and multiple Child dialogs.

All that you have to do, is derive your own dialog class from RipTABS' CTabDialog class and pass RipTABS the list of tab titles, and Child dialog resource names.


Function Groups

Library Initialization And Cleanup

RipTABRegister (see RipTABRegister)

RipTABUnregister (see RipTABUnregister)

InitData (see CTabDialog::InitData)

Construction

CTabDialog (see CTabDialog::CTabDialog)

Dialog Initialization And Cleanup

OnInitDialog (see CTabDialog::InitData)

OnDestroy (see CTabDialog::OnDestroy)

Painting

OnPaint (see CTabDialog::OnPaint)

User Actions

OnOK (see CTabDialog::OnOK)

OnCancel (see CTabDialog::OnCancel)

OnLButtonDown (see CTabDialog::OnLButtonDown)

Tab Navigation

NextTab (see CTabDialog::NextTab)

PrevTab (see CTabDialog::PrevTab)

SetActiveTab (see CTabDialog::SetActiveTab)

Tab Properties

SetTabText (see CTabDialog::SetTabText)

GetTabText (see CTabDialog::GetTabText)

EnableTab (see CTabDialog::EnableTab)

DisableTab (see CTabDialog::DisableTab)

IsTabEnabled (see CTabDialog::IsTabEnabled)

Notification Messages

SwitchFromNotification (see CTabDialog::SwitchFromNotification)

SwitchToNotification (see CTabDialog::SwitchToNotification)

OKToSwitch (see CTabDialog::OKToSwitch)


Things To Know & Remember

This section contains some important things to remember when using RipTABS, and a few caveats that you should bear in mind as you design and work with your dialogs.

•	While RipTABS tries to do its best to make a tab dialog look nice even if there are an odd number of tabs, you'll get the best results if you design your dialog to include an even number of tabs.  (An even number of tabs is a requirement if your are using vertical tabs.)  Remember to use the MaxTabsPerLine parameter in CTabDialog::InitData if you want to force a certain number of tabs to fit on a tab page.

•	Your tab dialog will look better if you pass in fonts (both normal and bold) in the call to CTabDialog::InitData so that the title of the active tab is highlighted.

•	Give your dialogs a Windows 95 look by using your resource editor to make the font in your master dialog MS Sans Serif, 8 point.  Then pass STDFont for all font parameters in InitData.

•	RipTABS switches between groups by disabling and hiding controls in any group that isn't currently active.  This means that if you need for certain controls to be disabled or hidden, it isn't good enough to simply mark the control as disabled or hidden in your resource editor.  Respond to the CTabDialog::SwitchToNotification message and find out what group has been made active.  Then send hide and disable messages to any controls that need them.

•	You can use DDX routines (DDX_Text etc.) to place and retrieve data into and from controls in the dialog.  The only problem is that ClassWizard can't generate the statements for you-- you'll have to add the DDX lines yourself but this requires relatively little effort.

•	Remember to return 0 or FALSE from your CTabDialog::OnInitDialog member function for any dialog derived from CTabDialog-- this tells Windows that you've specifically set focus to a control and that you want to override the default behavior of setting focus to the first control in a dialog.  RipTABS sets focus to the tab of whatever group has been made active.  If you don't return 0 from OnInitDialog, you're effectively overriding RipTABS' behavior.


Font Notes

This section describes some issues you need to keep in mind regarding fonts.

By default, dialogs in Windows 3.1 and Windows NT 3.5 use the bold system font for drawing the text in dialog controls.  More recently, many popular applications have adopted a new "look" for dialogs by using a less obtrusive font such as MS Sans Serif in 8 points for dialogs.  Whether you choose this look or something of your own choosing, RipTABS makes it easy.

How RipTABS will work with fonts in your dialogs depends on the parameters you pass in the InitData call (see CTabDialog::InitData) --There are a number of ways you can approach how fonts get used in your tabbed dialogs:

•	Pass in RipTABS-defined STDFont symbol for font parameters in InitData and RipTABS will build fonts for tabs and controls based on the dialog font defined in your resource editor (such as AppStudio) for the Master dialog.  Non-active tabs and dialog controls will be non-bold and active tabs will be bold.  To give your dialog a Windows 95 look, use your resource editor to set the Master Dialog font to MS Sans serif, 8 point.

•	Pass individual CFont pointers to InitData for fonts that you have already created in your application.  This way, you can customize how tabs and controls appear-- non-active tabs, active tabs and controls can all you distinct fonts.

The RipTABS sample application provided with this package uses the first technique.   Play with fonts in your own applications to see what works best for you.


Bitmap Notes

This section describes some issues you need to keep in mind if you use bitmaps in tabs.

You let RipTABS know you want it to display bitmaps in tabs by passing in an array of bitmap handles (see CTabDialog::InitData) during your call to InitData().

First off, unlike the other two arrays you pass to InitData, it is your responsibility to delete the bitmap array after the dialog has closed.  You should also free resources associated with the bitmaps by calling the Windows DeleteObject function for each one.

RipTABS will automatically expand the width of dialog tabs to accommodate the fact that tabs will display bitmaps in addition to text.  However, you should be careful about the size of the bitmaps because the height of each tab is determined by the tab font you've selected-- i.e. things are going to look funny if the bitmaps are taller than the text because they'll be "chopped-off".  If you want to use bitmaps that are a little larger, pass in a font that is large enough to accommodate them.


Troubleshooting

This section contains solutions for some commonly reported problems.

•	If your tab dialog is behaving strangely, the first thing to check is to make absolutely certain that all controls for all tab pages of a given dialog have unique identifiers.

•	If your CTabDialog implementation doesn't seem to be drawing tabs or otherwise behaving as a tab dialog, check to make sure that in the message map for your dialog, you are using CTabDialog and not CWnd or CDialog as the template for messages... i.e.
       BEGIN_MESSAGE_MAP(CRTabMDialog, CTabDialog) works,
       BEGIN_MESSAGE_MAP(CRTabMDialog, CDialog) doesn't.

•	If one of the tab pages in your dialog appears blank and then as you switch between groups, the rest of the pages start appearing blank as well, it is probably because you have passed RipTABS a bad dialog resource name in your CTabDialog::InitData call.  (Maybe a typo)


Requirements

For Windows 3.1 applications, you need Microsoft Visual C V1.5 with the Microsoft Foundation Classes V2.5 that comes with it.  For Windows NT, you'll need the Visual C++ V2.0 compiler along with MFC V3.0.

To use RipTABS, you must link the Microsoft Foundation Classes into your application as MFC support is required.  As of this release, there was a known problem linking to the DLL version of the MFC libraries-- hopefully a future version of the library will address this problem.

If you are using the demo version of RipTABS and Windows 3.1, you must make sure your application is built with for the Large Memory Model-- a Medium Memory Model version of the library will be made available to registered users. (Windows NT users can ignore this, there is no medium or large memory model in NT.)

Also, the demo library will only link properly if you are building in DEBUG mode in Visual C++.

The RipTABS library does not support being linked to MFC applications compiled as DLLs or applications using the DLL version of MFC.  However, if you get the RipTABS Source Code option, these last two restrictions don't apply.)


About The Sample Source Code

The source code for the RipTABS sample application (RSAMP16.EXE for Windows and RTAB32.EXE for Windows NT) is provided.  It was built with Visual C++ and its AppWizard.  Hardly anything was changed with respect to the generated code-- most of the RipTABS dialog code was added in a source code file call RTABDIAL.CPP and RTABDIAL.H.

The sample application demonstrates both Modal and Modeless dialogs with single and multiple pages of tab groups.  Play with the sample a little to find out how the tab dialog behaves.  Amongst other things, the sample demonstrates the proper way to initialize an RipTABS dialog, how to access controls directly, how to use MFC DDX to access controls, how to subclass controls and how to respond to a tab page switch initiated by the user.  The sample does not attempt to demonstrate all the capabilities of the RipTABS library but tries instead to give you enough to get tab dialogs up and running.  For more information about additional capabilities, please refer to the Reference section of this manual.

The Visual C++ project (.MAK) file was included (RSAMP16.MAK for Windows and RSAMP32.MAK for Windows NT) so that you can quickly compile the app yourself.  If you are going to try to recompile the provide source code and project file, you'll have to insure to update the project file with the proper paths to the various libraries etc.

The following sections discuss what code you add to your application to implement tab dialogs-- the sample source shown in this guide is taken from the sample source code provided.

The sample source code also makes use of CTL3D -- the DLL from Microsoft that gives a 3D look to dialogs.  It is recommended that you also use CTL3D in applications that use the RipTABS library because the two offer each other a complimentary "look".  If you don't have the CTL3D .LIB and .H file, you'll need to remove references to CTL3D from the sample source code before you can compile it.  To do this :

•	Remove the reference to CTL3D.H from STDAFX.H

•	Remove the initialization of CTL3D from InitInstance in RTAB_SAM.CPP.  (There are two lines to remove)

•	Remove the reference to CTL3D in ExitInstance in RTAB_SAM.CPP.


Building Your Dialogs (Resource Editor)

For your first implementation of  a RipTABS dialog, go simple.

The Folder Tab interface is designed to allow for a dialog to present a lot of information and options to the end user in a relatively small amount of space.  Pick an existing dialog that contains a lot of controls that can be logically grouped into two or more "families".

Create a new dialog with your resource editor and make it as large as necessary to fit the largest group of controls and three buttons-- Help, OK, and Cancel.  This is known as your Master dialog.  (see the next picture.)

In this dialog place three buttons (Help, OK, and Cancel) at the bottom right of the dialog.  Make sure that your OK button has a resource ID of IDOK and the Cancel button has a resource ID of IDCANCEL.  (This ensures appropriate default behavior for OnOK and OnCancel.)

Note that instead of placing the Cancel, Help and OK buttons in your master dialog, you can do as we have done in the sample and copy the same three buttons into all tab pages (or child dialogs).  Microsoft does this in their dialogs.

Next, draw a group box that extends from the top left of the dialog to the bottom right, but does not contain the three buttons.  Give this group box a unique resource ID-- doesn't matter what, but it must be unique.  All controls will be drawn inside of this box.  Save this dialog.

Now go ahead and create additional dialogs.  In each one, place the controls that you've designated as being a group.  (See the next picture)

It doesn't matter exactly how big each dialog is, but the controls must be placed relative to the upper left corner so that they'd fit if they were pasted into the master dialog's group control.  You don't need OK / Cancel buttons in these dialogs.   You also don't need to worry about the Caption text for each one-- only the controls from each dialog are used.

Again, the ID for these dialogs should be string based and not numeric.   (i.e. IDs like "ADIALOG" are ok, IDs like IDD_DIALOG are not.)


Adding The Support Code

Initializing and Uninitializing RipTABS

Deriving Your Dialog - Header File

Dialog Initialization - Overriding OnInitDialog

Implementing Help - Switch Notification Usage

Implementing OnOK

Implementing OnCancel

Implementing OnDestroy

Creating & Displaying The Dialog


Initializing and Uninitializing RipTABS

Before you access RipTABS functions from your code, you must call RipTABRegister() from your application's InitInstance member function.

Also, before you terminate, you must call RipTABUnregister()-- it is recommended you do this from your application's ExitInstance member function.

Examples of these two calls follow:

Code Sample - Initializing RipTABS library

BOOL CRtab_samApp::InitInstance()

{

  RipTABRegister();

  ...

}

Code Sample - Uninitializing RipTABS library

int CRtab_samApp::ExitInstance()

{

  RipTABUnregister();

  ...

}


Deriving Your Dialog - Header File

Declaring your dialog class is easy -- simply derive your class from CTabDialog instead of CDialog.  You'll also want a member variable -- a two dimensional CPtrArray* array.  The example below (part of the supplied sample source code) also includes overrides for OnInitDialog, message map functions to respond to the OK, Cancel and Help buttons, and a CString variable to hold the text that corresponds to the active page of our dialog.

Code Sample - Defining our tab dialog class.

class CRTabDialog : public CTabDialog

{

// Construction

public:

  CRTabDialog(CWnd* pParent = NULL);	// standard constructor

// Dialog Data

  //{{AFX_DATA(CRTabDialog)

  enum { IDD = IDD_RTABDIALOG };

  // NOTE: the ClassWizard will add data members here

  //}}AFX_DATA

// Implementation

protected:

  virtual void SwitchToNotification(int TabIndex, CString* TabName);

  // Generated message map functions

  //{{AFX_MSG(CRTabDialog)

  virtual BOOL OnInitDialog();

  virtual void OnOK();

  afx_msg void OnClickedHelp();

  virtual void OnCancel();

  //}}AFX_MSG

  DECLARE_MESSAGE_MAP()

protected:

  CPtrArray*	DlgOptionsList[2];

  CRtab_samView*	MyView;

  CString	ActivePage;

};


Dialog Initialization - Overriding OnInitDialog

The following code is an example of what goes into our OnInitDialog function.  We initialize our CPtrArray* array.  We are creating two CPtrArrays.  Each of these CPtrArrays holds pointers to character strings.  One CPtrArray (in this case DlgOptionsList[0]) holds the titles of our dialog tabs, and the other (DlgOptionsList[1]) holds the resource names of our dialogs (excluding the master dialog).

Please note that the two CPtrArrays hold pointers to regular C character arrays (strings) and not CStrings.  The CStringPtr function you see in the following example takes a literal string as an argument and returns a char*, which we cast to void* for storage in the CPtrArray.

After setting up the arrays, we call CTabDialog::InitData (See CTabDialog::InitData) which takes at least three arguments (the rest are optional): a pointer to the array of tab titles, a pointer to the array of resource names, and the resource value of the group box in the master dialog.

The sample source code included with this package shows how to use the optional parameters.  For more information on these parameters, have a look at the sample program and CTabDialog::InitData.  Also, if you are going to be using bitmaps in tabs, please see the special note titled Bitmap Notes.

Finally, before leaving our OnInitDialog, we call the CTabDialog version of OnInitDialog.  (See CTabDialog::OnInitDialog)

Once you have performed these steps, you may initialize dialog box controls (from the Master dialog or any of the Child dialogs) such as placing default text into edit controls, placing check marks in check box controls etc.  Don't attempt to do this before calling CTabDialog::InitData and CTabDialog::OnInitDialog.

You should return 0 or FALSE from your OnitDialog routine-- this tells Windows that you have specifically set focus to a control in your dialog (something RipTABS does).

Note : You should not delete the two CPtrArrays-- RipTABS will delete them after the dialog box closes.  Likewise, RipTABS will delete the strings created in memory for the tab titles.  You should delete the bitmap array if you use one, and the responsibility for freeing resources associated with the bitmaps is yours as well.

Code Sample - Initializing dialog, building our CPtrArrays

BOOL CRTabDialog::OnInitDialog()

{

  DlgOptionsList[0]= new CPtrArray();

  DlgOptionsList[0]->SetSize(0, 20);

  DlgOptionsList[1]= new CPtrArray();

  DlgOptionsList[1]->SetSize(0, 20);

  DlgOptionsList[0]->Add((void*)CStringPtr("Radio Buttons"));

  DlgOptionsList[0]->Add((void*)CStringPtr("Check Boxes"));

  DlgOptionsList[0]->Add((void*)CStringPtr("Edit Control"));

  DlgOptionsList[1]->Add((void*)CStringPtr("RADIO_DIALOG"));

  DlgOptionsList[1]->Add((void*)CStringPtr("CHECK_DIALOG"));

  DlgOptionsList[1]->Add((void*)CStringPtr("EDIT_DIALOG"));

  CTabDialog::InitData(DlgOptionsList[0], DlgOptionsList[1], IDC_RSTATIC);

  CTabDialog::OnInitDialog();

  // place your own controls intialization code here ...

  return TRUE;  // return TRUE  unless you set the focus to a control

}


Implementing Help - Switch Notification Usage

RipTABS provides three notification functions for determining when the user has clicked on a tab in our dialog and thus, switched pages.  Two of these notifications come after the active tab has been switched, and one comes prior to the switch. If you need to know what page a user has switched from or what page he has switched to, you'll need to know about SwitchFromNotification and SwitchToNotification.

SwitchFromNotification (See CTabDialog::SetActiveTab) gets called to let us know what page the user switched from.  Two parameters are passed : TabIndex and TabName.  TabIndex is the zero-based index of the page that the user switched from.  (This corresponds to the index in the array we passed in, in our call to InitData earlier.)  TabName is a pointer to a CString-- the tab title text.

SwitchToNotification (See CTabDialog::SwitchToNotification) gets called to let us know what page the user switched to.  Two parameters are passed : TabIndex and TabName.  TabIndex is the zero-based index of the page that the user switched to.  (This corresponds to the index in the array we passed in, in our call to InitData earlier.)  TabName is a pointer to a CString-- the tab title text.

In the example below, we make use of SwitchToNotification and assign the tab title to our own CString variable.  We use this to simulate tracking of help topics-- in other words, we'll be able to provide context sensitive help in our dialog-- based on the active page.

If you'd like to for some reason prevent a switch, the previous two notifications are sufficient because they come after the switch has taken place.  Rather, you should use the OKToSwitch function -- see CTabDialog::OKToSwitch.

Code Sample - Use SwitchToNotification to implement a crude form of context sensitive help.

void CRTabDialog::SwitchToNotification(int TabIndex, CString* TabName)

{

  ActivePage= *TabName;

}

void CRTabDialog::OnClickedHelp()

{

  CString MessageText="Display Help For : ";

  MessageText+=ActivePage;

  MessageBox(MessageText, "RipTABS Sample");

}

In the example above (OnClickedHelp), we display a dialog with the name of the currently-active tab page.  It wouldn't be a big leap from here to implement context-sensitive help.  (you'd probably track the tab index rather than the title though.)


Implementing OnOK

If you are going to implement a message map function for when the user clicks on the OK button, you should remember to call CTabDialog::OnOK (See CTabDialog::OnOK) before you finish.

Note that even though your controls are spread across many child dialogs, they are all accessible from your CTabDialog.

Code Sample - Responding to user's click on OK button

void CRTabDialog::OnOK()

{

  char str[101];

  CString CheckBoxStatus, RadioButtonStatus, EditControlStatus;

  if(IsDlgButtonChecked(IDC_CHECK1))

    MyView->CheckBoxStatus = "1";

  if(IsDlgButtonChecked(IDC_CHECK2))

    MyView->CheckBoxStatus = "2";

  if(IsDlgButtonChecked(IDC_CHECK3))

    MyView->CheckBoxStatus = "3";

...

  CTabDialog::OnOK();

}


Implementing OnCancel

If you are going to implement a message map function for when the user clicks on the Cancel button, you should remember to call CTabDialog::OnCancel (See CTabDialog::OnCancel) before you finish.

Note that even though your controls are spread across many child dialogs, they are all accessible from your CTabDialog.

Code Sample - Responding to user's click on the Cancel Button

void CRTabDialog::OnCancel()

{

  // TODO: Add extra cleanup here

  CTabDialog::OnCancel();

}


Implementing OnDestroy

If you are going to implement a message map function for the WM_DESTROY (or ON_WM_DESTROY) message, be sure to call the CTabDialog member function as well because RipTABS performs some important cleanup procedures here.

Code Sample - Responding to ON_WM_DESTROY

void CRTabDialog::OnDestroy()

{

  // TODO: Add extra cleanup here

  CTabDialog::OnDestroy();

}


Creating & Displaying The Dialog

The following code creates and displays the dialog.

void CRtab_samView::OnDoRipTABDialog()

{

CRTabDialog diag(this);

diag.DoModal();

}


Final Touch-Ups

As you modify, re-arrange your tab dialog, you may have to make slight adjustments to your master dialog size-- i.e. add a little more space on the left, or bottom etc.  There is some degree of imprecision in the translation of dialog units and precise pixel mapping.  On the whole though, you shouldn't have to do much to get things looking just right.


RipTABRegister

RipTABRegister();

This function takes no parameters.  It initializes RipTABS' internal structures.  Call this from your application's InitInstance member function.  It must be called before using any other RipTABS function.  Remember to call RipTABUnregister before your app terminates.

Parameters

None.

Returns

Nothing.


RipTABUnregister

RipTABUnregister();

This function takes no parameters.  It frees up RipTABS' internal structures.  Call this from your application's ExitInstance member function.

Parameters

None.

Returns

Nothing.


CTabDialog::CTabDialog

CTabDialog(int theDialog, CWnd* pParent = NULL, int theActiveTab=0, BOOL AllTheSame=FALSE, BOOL SquareTabs=FALSE, BOOL bVertical=FALSE);

CTabDialog(int theActiveTab=0, BOOL AllTheSame=FALSE, SquareTabs=FALSE, BOOL bVertical=FALSE);

Call this as part of the constructor of your derived dialog.

The first version of the constructor is for modal dialogs.  In other words, you call the CTabDialog constructor and then call DoModal().

The second version is for modeless dialogs.  After calling the CTabDialog constructor, you'll have to call the Create function to construct your dialog.  The sample source code demonstrates the use of a modeless dialog.

Parameters

theDialog
(For Modal Dialogs only)  Pass in the dialog template ID of your master dialog.

pParent
(For Modal Dialogs only)  Pass in a pointer to the CWnd that is to be the parent of this dialog.

theActiveTab
Normally, RipTABS brings up a dialog with the first Tab being the active Tab Group.  Pass in something other than 0 to override this behavior and designate a specific tab group as being initially active.  (The number passed should correspond to the index in the array of tabs you pass in during InitData())

AllTheSame
Set this parameter to TRUE if all Tab Groups will be constructed from the same child dialog template.  Usually, you will use this option when all you want is a dialog with tab groups without any controls because you'll be drawing the interior of the dialog yourself.  See the notes in CTabDialog::InitData for special notes about using this parameter.

SquareTabs
Set this parameter to TRUE if you want tabs to be drawn with square (right angle) edges, rather than the default rounded edges.

bVertical
Set this parameter to TRUE if you want the tabs arranged vertically down the left side of the dialog.  Tab title text will be rotated 90 degrees.


CTabDialog::DisableTab

void DisableTab(int nTab);

Call this function to disable a tab.  A disabled tab cannot be activated by the user and the title text of a disabled tab visually indicates that the tab has been disabled.  Disable a tab if you need to prevent the user from accessing its contents for some reason.

Parameters

nTab
This parameter corresponds to an element in the array of dialogs you passed in during InitData.  (See CTabDialog::InitData)

Returns

Nothing.


CTabDialog::EnableTab

void EnableTab(int nTab);

Call this function to enable a tab.  An enabled tab can be activated by the user.  You would normally use this function after having previously disabled a tab.

Parameters

nTab
This parameter corresponds to an element in the array of dialogs you passed in during InitData.  (See CTabDialog::InitData)

Returns

Nothing.


CTabDialog::GetTabText

CString GetTabText(int nTab);

Call this function to retrieve the title text of a particular tab.

Parameters

nTab
This parameter corresponds to an element in the array of dialogs you passed in during InitData.  (See CTabDialog::InitData)

Returns

A CString object.


CTabDialog::InitData

void InitData(CPtrArray* theOptionsList1, CPtrArray* theOptionsList2,

int TheStaticBox, int theActiveTab=-1, CWordArray* theBitmapList=NULL, CDWordArray* theTabTextColorList=NULL, CFont* pNormalFont=NULL, CFont* pBoldFont=NULL, CFont* pControlFont=NULL , COLORREF cActiveTabTextColor=0, int MaxTabsPerLine=32000);

Call this after you've set up your arrays of tab titles and child dialog resource names.

Parameters

 theOptionsList1
This is your array of tab titles-- all of the elements must be pointers to CStrings.  None of the elements may be NULL.

 theOptionsList2
This is your array of child dialog template names.  If you set the AllTheSame parameter in the constructor of CTabDialog to TRUE, then all elements of this array (except for the first) may be NULL.  (However, the size of this array must always be the same size or have the same number of elements as the array designated for theOptionsList1)

TheStaticBox
The resource ID of the static group box in the Master dialog that will surround all the controls from your child dialogs.  Do not pass in the default IDC_STATIC ID that AppStudio defaults to--- this must be a unique identifier.

theActiveTab
Normally, RipTABS brings up a dialog with the first Tab being the active Tab Group.  Pass in something other than 0 to override this behavior and designate a specific tab group as being initially active.  (The number passed should correspond to the index in the array of tabs you pass in -- i.e. theOptionsList1 & theOptionsList2)

theBitmapList
This is an optional array of HBITMAPs (handles to bitmaps) that you'd like to have displayed with each tab.  Each entry in this array corresponds to the entries in TheOptionsList1 & TheOptionsList2.  Unlike those two arrays, you must delete this array yourself after the dialog closes and you should call the Windows function DeleteObject for each bitmap you've created or loaded.  If you aren't going to be displaying bitmaps, pass a NULL value for this parameter.  See the special note on bitmaps for more important information (Bitmap Notes).

theTabTextColouList
This is an optional array of COLORREFS (RGB values) that you'd like RipTABS to use to paint the text in each tab.  Each entry in this array corresponds to the entries in TheOptionsList1 & TheOptionsList2.  Unlike those two arrays, you must delete this array yourself after the dialog closes. If you don't want to specify custom color values, pass a NULL value for this parameter.

pNormalFont
RipTABS can display two types of fonts in the tabs-- one for the active tab, and one for all others.  pNormalFont is a CFont* that gets used for non-active tabs.  If you pass NULL then RipTABS will use the default dialog font for tab display.   Alternatively, you can pass STDFont (a constant defined in the RipTABS header) and RipTABS will choose and build an appropriate font for this parameter.

pBoldFont
This CFont* gets used for the active tab.  If you pass NULL then RipTABS will use the default dialog font for tab display. You should pass CFont*s for  pNormalFont, pBoldFont and pControlFont or neither of them-- don't just set one. Alternatively, you can pass STDFont (a constant defined in the RipTABS header) and RipTABS will choose and build an appropriate font for this parameter.

pControlFont
This CFont* gets used for all control on the tab pages.  If you pass NULL then RipTABS will use the default dialog font for tab display.  You should pass CFont*s for  pNormalFont, pBoldFont and pControlFont or neither of them-- don't just set one. Alternatively, you can pass STDFont (a constant defined in the RipTABS header) and RipTABS will choose and build an appropriate font for this parameter.

cActiveTabTextColor
Use this parameter to pass the color that RipTABS should use to draw the text in the currently active tab.

MaxTabsPerLine
Normally, RipTABS scans your tab text and tries to fit the most tabs it can on each set of tab lines or pages.  You may want to limit the number of tabs per page to keep equal numbers of tabs per page or for some other reason.

Returns

Nothing.


CTabDialog::IsTabEnabled

BOOL IsTabEnabled(int nTab);

Call this function to determine whether a particular tab is enabled.  See CTabDialog::IsTabEnabled for information on the difference between enabled and disabled tabs.

Parameters

nTab
This parameter corresponds to an element in the array of dialogs you passed in during InitData.  (See CTabDialog::InitData)

Returns

TRUE if the tab is enabled, FALSE if the tab is disabled.


CTabDialog::NextTab

void NextTab();

Call this function to cause the dialog to display the next tab group --i.e. the tab immediately following the currently active one.

Parameters

None.

Returns

Nothing.


CTabDialog::PrevTab

void PrevTab();

Call this function to cause the dialog to display the previous tab group --i.e. the tab immediately preceding the currently active one.

Parameters

None.

Returns

Nothing.


CTabDialog::OKToSwitch

virtual BOOL OKToSwitch(int TabIndex, CString* TabName);

A notification function that gets called before the dialog is about to have the active tab changed.  The default implementation always permits a switch by returning TRUE.  Override this function if you need to customize this behavior.

Parameters

TabIndex
TabIndex is the zero-based index of the page the use is attempting to switch to.  (Corresponds to the array you passed in during InitData.)

TabName
TabName is a pointer to the title (text) of the page the user is switching to.

Returns

TRUE or FALSE.  Return TRUE if RipTABS is to permit the switch, or FALSE otherwise.


CTabDialog::OnCancel

virtual void OnCancel();

If you are going to override OnCancel for your own purposes (to retrieve information from the dialog's controls), be sure to finish off by calling the CTabDialog version of OnCancel because this function performs important cleanup steps.

Parameters

None.

Returns

Nothing.


CTabDialog::OnDestroy

afx_msg void OnDestroy();

If you are going to override OnDestroy for your own purposes, be sure to finish off by calling the CTabDialog version of OnDestroy because this function performs important cleanup steps.

Parameters

None.

Returns

Nothing.


CTabDialog::OnInitDialog

virtual BOOL OnInitDialog();

Be sure to call the CTabDialog version of OnInitDialog as this performs the necessary construction of tabs and pages etc.

Parameters

None.

Returns

Nothing.


CTabDialog::OnLButtonDown

afx_msg void OnLButtonDown(UINT flags, CPoint point);

This member function handles left-button clicks to see if the user has clicked on a tab.  if you need to check for this message to, be sure to call the CTabDialog version as well.

Parameters

Standard MFC parameters-- see your MFC documentation.

Returns

Nothing.


CTabDialog::OnOK

virtual void OnOK();

If you are going to override OnOK for your own purposes (to retrieve information from the dialog's controls), be sure to finish off by calling the CTabDialog version of OnOK because this function performs important cleanup steps.

Parameters

None.

Returns

Nothing.


CTabDialog::OnPaint

afx_msg void OnPaint();

This member function paints the interior of the dialog-- tabs, titles etc.  If you are going to override the OnPaint for some reason, be sure to call the CTabDialog version of it.

Parameters

None.

Returns

Nothing.


CTabDialog::SetActiveTab

void SetActiveTab(int theTab);

Call this function to cause the dialog to display the tab group designated by theTab.

Parameters

theTab
This parameter corresponds to an element in the array of dialogs you passed in during InitData.  (See CTabDialog::InitData)

Returns

Nothing.


CTabDialog::SetTabText

void SetTabText(int nTab, LPCSTR szText);

Call this function to change the title of a particular tab.

Parameters

nTab
This parameter corresponds to an element in the array of dialogs you passed in during InitData.  (See CTabDialog::InitData)

szText
A string containing the text you want to set as the new title of the tab.

Returns

Nothing.


CTabDialog::SwitchToNotification

virtual void SwitchToNotification(int TabIndex, CString* TabName);

A notification function that gets called when a user clicks on a dialog tab and thus switches pages.

Parameters

TabIndex
TabIndex is the zero-based index of the page the use is switching to.  (Corresponds to the array you passed in during InitData.)

TabName
TabName is a pointer to the title (text) of the page the user switched to.

Returns

Nothing.


CTabDialog::SwitchFromNotification

virtual void SwitchFromNotification(int TabIndex, CString* TabName);

A notification function that gets called when a user clicks on a dialog tab and thus switches pages.

Parameters

TabIndex
TabIndex is the zero-based index of the page the use is switching from.  (Corresponds to the array you passed in during InitData.)

TabName
TabName is a pointer to the title (text) of the page the user switched from.

Returns

Nothing.


Glossary of Terms
Glossary of TermsError! Bookmark not defined.

MFC

STDFont

Child Dialog

Master Dialog


MFC

Abbreviation for Microsoft Foundation Classes: the C++ class library that comes with the Microsoft Visual C++ compiler.


STDFont

A constant symbol defined by RipTABS that lets RipTABS know that you want it to handle creating and destroying the fonts used to display tabs or dialog controls.


Child Dialog

These are defined as dialogs in your resource editor but will show up as tab pages in the Master Dialog at run-time.  There is one Child Dialog for each tab you want in the Master Dialog.


Master Dialog

The primary dialog in which the tabs and tab pages will be displayed.